package com.newtouch.cq.security.config.detail;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.newtouch.cq.lang.cache.CacheAble;
import com.newtouch.cq.lang.config.CacheProperties;
import com.newtouch.cq.lang.config.TokenCacheProperties;
import com.newtouch.cq.lang.em.BaseExceptionEnum;
import com.newtouch.cq.lang.exception.MccBizException;
import com.newtouch.cq.lang.util.LogUtil;
import com.newtouch.cq.security.exception.AuthException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

public class CustomAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {

	@Autowired private CacheAble cacheAble;

	private Log log = LogFactory.get(CustomAuthenticationDetailsSource.class);


	private static List<String> NOT_AUTHENTICATIONS = CollUtil.newArrayList();

	static {
        NOT_AUTHENTICATIONS.add("/auth/token");
		NOT_AUTHENTICATIONS.add("/auth/loginPage");
	}

    @Override
    public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
    	CustomWebAuthenticationDetails details =  new CustomWebAuthenticationDetails(context);
    	if(TokenCacheProperties.enableloginValidateCode && StrUtil.isNotEmpty(details.getRandomKey())) {
    		if(StrUtil.isEmpty(details.getCode())) {
				LogUtil.error(log,BaseExceptionEnum.VERIFICATION_CODE_NO_NULL);
    			throw new AuthException(BaseExceptionEnum.VERIFICATION_CODE_NO_NULL);
    		}
    		String code = (String) cacheAble.get(CacheProperties.imageCodePrifix+details.getRandomKey());
    		if(StrUtil.equals(code, details.getCode())) {
    			cacheAble.delete(CacheProperties.imageCodePrifix+details.getRandomKey());
			} else  {
				LogUtil.error(log,BaseExceptionEnum.VERIFICATION_CODE_ERROR_INVALID);
				throw new AuthException(BaseExceptionEnum.VERIFICATION_CODE_ERROR_INVALID);
    		}
    	}

//		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//
//		String requestURI = context.getRequestURI();
//    	if(!CollUtil.contains(NOT_AUTHENTICATIONS,requestURI) && !CollUtil.contains(MccOauth2Properties.urlPermitAll,requestURI) && MccOauth2Properties.authentication) {
//			authentication(authentication,requestURI);
//		}
        return details;
    }

	/**
	 * 鉴权
	 * @param userDetails
	 */
	private void authentication(Authentication userDetails, String requestURI) {
		List<String> permissionUrls = CollUtil.newArrayList();

		userDetails.getAuthorities().forEach(grantedAuthority -> {
			permissionUrls.add(grantedAuthority.getAuthority());
		});

		if(!CollUtil.contains(permissionUrls,requestURI)) {
			LogUtil.error(log,BaseExceptionEnum.INSUFFICIENT_PERMISSIONS);
			throw new AuthException(BaseExceptionEnum.INSUFFICIENT_PERMISSIONS);
		}
	}

}
